//
// Created by Administrator on 2023/4/11.
//

#ifndef WEBRTC_MODEL_JITTERANALYZE_H
#define WEBRTC_MODEL_JITTERANALYZE_H

#include <bits/stdc++.h>

using namespace std;

struct Packet {
    int sequenceNumber{};
    long long captureTime{};
    long long receiveTime{};
    long long absSendTime{};
    long long uuid{};
    //时延抖动，单位ms
    long long jitter{};

    Packet() = default;

    Packet(int sequenceNumber, long long int captureTime, long long int receiveTime, long long int absSendTime,
           long long int uuid) : sequenceNumber(sequenceNumber), captureTime(captureTime), receiveTime(receiveTime),
                                 absSendTime(absSendTime), uuid(uuid) {}

    bool operator<(const Packet &anotherPacket) const {
        if (receiveTime != anotherPacket.receiveTime) {
            return receiveTime < anotherPacket.receiveTime;
        }
        if (abs(sequenceNumber - anotherPacket.sequenceNumber) > 30000) {
            return sequenceNumber > anotherPacket.sequenceNumber;
        }
        return sequenceNumber < anotherPacket.sequenceNumber;
    }

    //计算绝对发送时间之差
    long long int diffAbsSendTime(long long int anotherAbsSendTime) const {
        //一个周期是64000
        if (abs(anotherAbsSendTime - absSendTime) > 30000) {
            long long diff = 64000 - max(absSendTime, anotherAbsSendTime) + min(absSendTime, anotherAbsSendTime);
            int flag = absSendTime < anotherAbsSendTime ? 1 : -1;
            return flag * diff;
        }
        return absSendTime - anotherAbsSendTime;
    }

    long long computeJitter(Packet &anotherPacket) const {
        return (receiveTime - anotherPacket.receiveTime) - diffAbsSendTime(anotherPacket.absSendTime);
    }
};

struct LatePacket {
    long long uuid;

    explicit LatePacket(long long int uuid) : uuid(uuid) {}
};

struct JitterData {
    int count;
    int lateCount;
};

struct SignalData {
    long long uuid{};
    string info;

    SignalData(long long int uuid, string info) : uuid(uuid), info(std::move(info)) {}

    SignalData() = default;
};

struct FramePackets {
    vector<Packet> packets;
    //最后一个数据包作为帧编号
    long long frameId{};
    //最后一个数据包的到达时间
    long long lastReceiveTimestamp{};
    //帧采集时间
    long long captureTime{};

    FramePackets(const vector<Packet> &packets, long long int frameId, long long int lastReceiveTimestamp,
                 long long int captureTime) : packets(packets), frameId(frameId),
                                              lastReceiveTimestamp(lastReceiveTimestamp), captureTime(captureTime) {}

    FramePackets() = default;

};

class JitterAnalyze {
private:
    //所有数据包
    vector<Packet> allUnsortedPacketsList;
    //抖动分布
    map<long long, JitterData> jitterResult;
    //信号
    vector<SignalData> signalDataList;

    static void outputSortedPackets(vector<Packet> &sortedPackets) {
        ofstream sortedPacketsOutput;
        sortedPacketsOutput.open("log/sortedPacketsOutput.csv", ios::out | ios::app);
        for (const auto &sortedPacket: sortedPackets) {
            sortedPacketsOutput << sortedPacket.sequenceNumber << "," << sortedPacket.captureTime << ","
                                << sortedPacket.receiveTime << "," << sortedPacket.absSendTime << endl;
        }
    }

    // 16777215
    // 111111.111111111111111111
    // 63.999996185302734
    static long long computeAbsSendTime(long long absSendTime) {
        double base = 32;
        double total = 0;
        for (int i = 0; i < 24; ++i) {
            if ((absSendTime >> (23 - i)) & 1) {
                total += base;
            }
            base /= 2;
        }
        return static_cast<long long>(total * 1000);
    }

    //frame1是否在frame2前面发送，如果是就返回true
    static bool aheadOf(const FramePackets &frame1, const FramePackets &frame2) {
        if (abs(frame1.captureTime - frame2.captureTime) > 4000000000) {
            return frame1.captureTime > frame2.captureTime;
        }
        return frame1.captureTime < frame2.captureTime;
    };

    /**
     * 对allPacketsList进行排序，排序结果放在sortedReceivePackets
     */
    vector<Packet> sortReceivePackets() {
        //接收端按照发送顺序排好序的数据包
        vector<Packet> sortedReceivePackets;
        //排序用的帧缓冲区
        map<long long, FramePackets> frameBuffer;
        for (auto iter = allUnsortedPacketsList.begin(); iter != allUnsortedPacketsList.end(); iter++) {
            const Packet &packet = *iter;
            frameBuffer[packet.captureTime].packets.push_back(packet);
            //接收时间每隔每30000000ms进行一次这样的排序
            if ((iter + 1) == allUnsortedPacketsList.end() ||
                (iter + 1)->receiveTime - frameBuffer.begin()->second.packets[0].receiveTime > 30000000) {
                //到了一个周期，处理一次
                vector<FramePackets> frames;
                for (auto &frame: frameBuffer) {
                    vector<Packet> &packets = frame.second.packets;
                    //将帧内按照序列号进行排序
                    sort(packets.begin(), packets.end(), [&](const Packet &p1, const Packet &p2) {
                        if (p1.sequenceNumber != p2.sequenceNumber) { return p1.sequenceNumber < p2.sequenceNumber; }
                        if (abs(p1.absSendTime - p2.absSendTime) > 30000) {
                            return p1.absSendTime > p2.absSendTime;
                        }
                        return p1.absSendTime < p2.absSendTime;
                    });

                    for (int i = static_cast<int>(packets.size() - 1); i >= 1; i--) {
                        if (packets[i].sequenceNumber == packets[i - 1].sequenceNumber) {
                            packets.erase(packets.begin() + i);
                        }
                    }

                    int loopFindIndex = 1;
                    for (; loopFindIndex < packets.size(); loopFindIndex++) {
                        if (packets[loopFindIndex].sequenceNumber - packets[loopFindIndex - 1].sequenceNumber > 30000) {
                            break;
                        }
                    }
                    if (loopFindIndex != packets.size()) {
                        for (int i = 0; i < loopFindIndex; i++) {
                            packets.push_back(*packets.begin());
                            packets.erase(packets.begin());
                        }
                    }
                    frames.emplace_back(packets, packets.back().sequenceNumber, packets.back().receiveTime,
                                        packets.back().captureTime);
                }
                //对帧进行排序
                //对帧按照到达时间进行基本的排序
                sort(frames.begin(), frames.end(), [&](const FramePackets &frame1, const FramePackets &frame2) {
                    return frame1.lastReceiveTimestamp < frame2.lastReceiveTimestamp;
                });
                //解决帧乱序的小型缓冲区
                vector<FramePackets> sortFrameBuffer;

                for (const auto &frame: frames) {
                    sortFrameBuffer.push_back(frame);
                    //冒泡排序
                    for (auto i = sortFrameBuffer.size() - 1; i > 0; i--) {
                        if (aheadOf(sortFrameBuffer[i], sortFrameBuffer[i - 1])) {
                            swap(sortFrameBuffer[i], sortFrameBuffer[i - 1]);
                        }
                    }
                    //经过一百次冒泡排序，可以认为第一个帧是最老的帧,复杂度就是100*帧内数据包
                    if (sortFrameBuffer.size() > 100) {
                        for (const auto &sortedPacket: sortFrameBuffer[0].packets) {
                            sortedReceivePackets.push_back(sortedPacket);
                        }
                        sortFrameBuffer.erase(sortFrameBuffer.begin());
                    }
                }
                //把剩下的帧内数据包放进去
                for (const auto &frame: sortFrameBuffer) {
                    for (const auto &sortedPacket: frame.packets) {
                        sortedReceivePackets.push_back(sortedPacket);
                    }
                }
                //清空缓冲区
                frameBuffer.clear();
            }
        }
        return sortedReceivePackets;
    }

    void inputPacketsData(vector<LatePacket> &latePacketList) {
        int sequenceNumber_;
        long long captureTime_;
        long long receiveTime_;
        long long absSendTime_;
        long long uuid_;

        //重复数据包并不会参与组帧，所以处理时延的时候应该删除
        set<long long> duplicatePackets;

        //记录重复数据包，便于后面删除
        ifstream latePackets;
        string latePacketsFilePath = "log/latePacket.log";
        latePackets.open(latePacketsFilePath, ios::in);
        string note;
        while (latePackets >> uuid_ >> note) {
            if (note == "duplicate") {
                duplicatePackets.insert(uuid_);
            } else {
                latePacketList.emplace_back(uuid_);
            }
        }

        string packetFilePath = "log/comePacket.log";
        ifstream allPackets;
        allPackets.open(packetFilePath, ios::in);
        while (allPackets >> sequenceNumber_ >> captureTime_ >> receiveTime_ >> absSendTime_ >> uuid_) {
            if (absSendTime_ == 0) { continue; }
            if (duplicatePackets.find(uuid_) != duplicatePackets.end()) { continue; }
            allUnsortedPacketsList.emplace_back(sequenceNumber_, captureTime_, receiveTime_,
                                                computeAbsSendTime(absSendTime_), uuid_);
        }
    }

    void computeJitterLate(const vector<LatePacket> &latePacketList, vector<Packet> &allSortedPackets) {//计算每个数据包的抖动
        for (int i = 1; i < allSortedPackets.size(); ++i) {
            long long jitter = allSortedPackets[i].computeJitter(allSortedPackets[i - 1]);
            allSortedPackets[i].jitter = jitter;
            jitterResult[jitter].count++;
        }

        //将uuid作为索引
        map<long long, Packet> packetMap;
        for (const auto &packet: allSortedPackets) {
            packetMap[packet.uuid] = packet;
        }

        //遍历迟到数据包 计算抖动造成数据包迟到的数量
        for (const auto &latePacket: latePacketList) {
            if (packetMap.find(latePacket.uuid) != packetMap.end()) {
                auto jitter = packetMap[latePacket.uuid].jitter;
                if (jitterResult.find(jitter) != jitterResult.end()) {
                    jitterResult[jitter].lateCount++;
                }
            }
        }
    }

    //计算均值和方差
    void computeMeanVariance(const vector<double> &numberList) {
        double total = 0;
        double variance = 0;
        for (const auto &number: numberList) {
            total += number;
        }
        double mean = total / static_cast<double >(numberList.size());
        for (const auto &number: numberList) {
            variance += (number - mean) * (number - mean);
        }
        cout << mean << " " << sqrt(variance) << endl;
    }

    void outputJitterMeanAndVariance() {
        vector<double> jitterList;
        for (const auto &item: jitterResult) {
            for (int i = 0; i < item.second.count; i++) {
                jitterList.push_back((double) item.first);
            }
        }
        computeMeanVariance(jitterList);
    }

    /**
     * 计算丢弃缓冲区的概率
     * @param allSortedPackets 所有排过序的数据包
     */
    void computeLoseBufferPercent(const vector<Packet> &allSortedPackets) {
        long long uuid_;
        string info_;
        ifstream signalInput;
        signalInput.open("log/signal.log", ios::in);
        while (signalInput >> uuid_ >> info_) {
            signalDataList.emplace_back(uuid_, info_);
        }
        cout << "丢弃缓冲区的概率为：" << (double) signalDataList.size() / (double) allSortedPackets.size() << endl;
    }

    void outputJitterDistribution(const vector<Packet> &allSortedPackets) {
        ofstream jitterOutput;
        jitterOutput.open("log/jitterDistribution.csv", ios::out | ios::app);
        for (const auto &item: jitterResult) {
            if (item.second.count == 0) { continue; }
            jitterOutput << item.first << "," << (double) item.second.count /
                                                 static_cast<double>((allSortedPackets.size() - 1)) << endl;
        }
    }

    void outputJitterLateRate() {
        ofstream jitterLateRate;
        jitterLateRate.open("log/jitterLateRate.csv", ios::out | ios::app);
        for (const auto &item: jitterResult) {
            if (item.second.lateCount == 0) { continue; }
            jitterLateRate << item.first << "," << (double) item.second.lateCount / (double) item.second.count << endl;
        }
    }

public:
    /**
    * 获得时延抖动造成数据迟到的概率
    */
    void getJitterLateRate() {
        //迟到的数据包信息
        vector<LatePacket> latePacketList;
        //输入所有数据包信息和丢包信息
        inputPacketsData(latePacketList);
        //对数据包按照发送顺序进行排序和去重
        auto allSortedPackets = sortReceivePackets();
        //输出测试效果
        outputSortedPackets(allSortedPackets);
        //计算抖动和迟到的对应关系
        computeJitterLate(latePacketList, allSortedPackets);
        //输出抖动和数据包迟到的关系
        outputJitterLateRate();
        //输出抖动分布
        outputJitterDistribution(allSortedPackets);
        //计算抖动的均值和标准差
        outputJitterMeanAndVariance();
        //计算丢弃缓冲区的概率
        computeLoseBufferPercent(allSortedPackets);
    }
};

#endif //WEBRTC_MODEL_JITTERANALYZE_H
